1. 案例1,无缓冲信道导致死锁, -> 运行死锁
// 不设定容量创建的是无缓冲信道,在接收者未准备好之前信道处于阻塞状态,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
package main func main(){ // 例如本案例:fatal error: all goroutines are asleep - deadlock! // sch := make(chan string) // sch <- "string" // fmt.Println(<-sch) // 处理方法,使用双协程,并且接收者在发送者就绪之前,-> 运行正常 // sch := make(chan string) // // go func() { // fmt.Println(<-sch) // 接收者就绪 // }() // // time.Sleep(time.Second) // sch <- "string" } |
2.案例2,改用有缓冲的信道, -> 运行正常
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
package main func main() { // 案例2,改用有缓冲的信道, -> 运行正常 // sch := make(chan string, 1) // sch <- "hello" // fmt.Println(<-sch) // 有缓冲信道导致的死锁,因信道容量满了,再向信道添加数据会产生阻塞,后续无法消费,从而导致死锁 - >运行死锁 // sch := make(chan string, 1) // sch <- "hello" // sch <- "world" // 因信道满了,无法接收数据从而产生阻塞 // fmt.Println(<-sch) // 解决方法,生产者跟消费者区分开来,使用不同的协程 sch := make(chan int, 1) go func() { count := 0 for { sch <- count count++ } close(sch) // 生产者不再生产消息,关闭掉通道即可 }() go func() { for { fmt.Println(<-sch) } }() select {} } |
3. 案例3,消费者一直空等待,并无生产者再生产消息,导致程序阻塞产生死锁 -> 运行死锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
package main func main() { // 案例3,消费者一直空等待,并无生产者再生产消息,导致程序阻塞产生死锁 -> 运行死锁 // pipLine := make(chan string) // go func() { // pipLine <- "hello world" // pipLine <- "hello China" // }() // // 再无消息消费,造成另一方无穷等待,造成死锁 // // fatal error: all goroutines are asleep - deadlock! // for data := range pipLine { // fmt.Println(data) // } // 解决方法 // 生产者不再生产消息时,关掉该信道,从而避免消费者傻等待造成死锁 go func() { pipLine <- "hello world" pipLine <- "hello China" close(pipline) }() select {} } |
4.案例4,无缓冲通道,当消费者结束,生产者也应该有检测机制,发现消费者没了,应该停止生产,并关闭掉通道,否则会造成死锁,如下代码:????
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
package main import ( "fmt" ) var index uint64 = 0 func main() { // 案例4,无缓冲通道,当消费者结束,生产者也应该有检测机制,发现消费者没了,应该停止生产,并关闭掉通道,否则会造成死锁,如下代码: // fatal error: all goroutines are asleep - deadlock! sch := make(chan uint64) go func() { count := 0 for { if count == 10 { // break // 消费者推出,会造成死锁 } fmt.Println("read = ", <-sch) count++ // time.Sleep(time.Second) } }() go func() { for { index++ if index == 10 { index = 0 } sch <- index // time.Sleep(time.Second) } }() // 处理方法,生产消费必须同时存在,或者消费者推出,生产者能感知,并且主动关闭掉通道 // 主程 select {} } |
「三年博客,如果觉得我的文章对您有用,请帮助本站成长」
共有 0 - golang-channel造成死锁案例